/*
 * Copyright (c) 2009 John Pritchard, WTKX Project Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package wtkx.ui;

import java.awt.font.GlyphVector;

/**
 * The text cursor shape.
 *
 * @see Position
 * @see Selection
 * @author jdp
 */
public final class Caret 
    extends GV
    implements GV.Aware
{

    public final int position, gvline, gvcolumn, gvcpstart, gvcpend;

    public final boolean trailing, start, in, end;

    public final float x, y, width, height;


    public Caret(GV g, Position p){
        super(g);
        this.position = p.offset;
        this.trailing = p.trailing;

        GlyphVector[] glyphs = this.glyphs;
        float leading = this.leading, lineheight = this.lineheight;
        float cix = this.ix, ciy = this.iy;

        float bx = cix, by = ciy;
        boolean start = false, in = false, end = false;
        {
            int gvline = 0, gvcolumn = this.position, gvcps = 0, gvcpe = 0;
            int count = (null != glyphs)?(glyphs.length):(0);
            if (0 < count){
                float[] glp = new float[2];
                for (; gvline < count; gvline++){
                    GlyphVector gv = glyphs[gvline];
                    int gvc = gv.getNumGlyphs();

                    if (gvcolumn < gvc){

                        if (p.trailing)
                            bx += GV.PositionR(gv,gvcolumn,glp);
                        else
                            bx += GV.PositionL(gv,gvcolumn,glp);

                        gvcpe = (gvcps+gvc);

                        if (0 == gvcolumn)
                            start = true;
                        else if (gvcolumn == (gvc-1))
                            end = true;
                        else
                            in = true;

                        break;
                    }
                    else if (0 == gvcolumn){

                        start = true;
                        end = true;

                        gvcpe = gvcps;

                        break;
                    }
                    else {
                        gvcolumn -= gvc;
                        gvcps += gvc;
                        by += lineheight;
                    }
                }
            }
            else {
                bx += leading;
            }

            this.start = (start||((!end)&&(!in)));
            this.in = in;
            this.end = end;
            this.gvline = gvline;
            this.gvcolumn = gvcolumn;
            this.gvcpstart = gvcps;
            this.gvcpend = gvcpe;
        }
        {
            float ax = bx;
            float lx = ax-0.5f;
            float ay = by+leading;
            float hh = (lineheight-leading-1f);
            {
                this.x = lx-1f;        //(clean clip)
                this.y = ay;           //
                this.width  = 5f;      //
                this.height = hh+1f;   //
            }
            this.moveTo(lx,ay);
            float zx = ax + 1.5f;
            this.lineTo(zx,ay);
            float ix = ax + 0.5f;
            this.moveTo(ix,ay);
            float zy = ay + hh;
            this.lineTo(ix,zy);
            this.moveTo(lx,zy);
            this.lineTo(zx,zy);
        }
    }
    public boolean is(Position p){
        if (null == p)
            return false;
        else
            return (this.position == p.offset);
    }
    public boolean isNot(Position p){
        if (null == p)
            return true;
        else
            return (this.position != p.offset);
    }
}
